package com.atguigu.yygh.user.service.impl;

import com.atguigu.yygh.common.result.Result;
import com.atguigu.yygh.model.user.Account;
import com.atguigu.yygh.user.mapper.AccountMapper;
import com.atguigu.yygh.user.service.AccountService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wf.captcha.ArithmeticCaptcha;
import com.wf.captcha.GifCaptcha;
import com.wf.captcha.SpecCaptcha;
import com.wf.captcha.base.Captcha;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class AccountServiceImpl
        extends ServiceImpl<AccountMapper, Account> implements AccountService {
    @Autowired
    private Random random;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    private AccountService accountService;

    public static final int[] captcha_font_types = {Captcha.FONT_1,
            Captcha.FONT_2, Captcha.FONT_3, Captcha.FONT_4,
            Captcha.FONT_5, Captcha.FONT_6, Captcha.FONT_7,
            Captcha.FONT_8, Captcha.FONT_9, Captcha.FONT_10};


    @Override
    public void createCaptcha(HttpServletResponse response, String captchaKey) {
        try {
            if (StringUtils.isEmpty(captchaKey) || captchaKey.length() < 13) {
                return;
            }
            long key = 0;
            try {
                key = Long.parseLong(captchaKey);
            } catch (Exception e) {
                return;
            }
            // 设置请求头为输出图片类型
            response.setContentType("image/gif");
            response.setHeader("Pragma", "No-cache");
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expires", 0);
            int captchaType = random.nextInt(3);
            Captcha targetCaptcha = null;
            if (captchaType == 0) {
                // 三个参数分别为宽、高、位数
                targetCaptcha = new SpecCaptcha(200, 60, 5);
            } else if (captchaType == 1) {
                // git 类型
                targetCaptcha = new GifCaptcha(200, 60);
            } else {
                // 算术类型
                targetCaptcha = new ArithmeticCaptcha(200, 60);
                targetCaptcha.setLen(2);
                targetCaptcha.text();
            }

            int index = random.nextInt(captcha_font_types.length);
            log.info("captcha font type index == > " + index);
            targetCaptcha.setFont(captcha_font_types[index]);
            //  数字和字母混合
            targetCaptcha.setCharType(Captcha.TYPE_DEFAULT);
            String content = targetCaptcha.text().toLowerCase();
            log.info("captcha content == >" + content);
            // 保存到 redis
            redisTemplate.opsForValue().set("yygh_" + key, content, 10, TimeUnit.MINUTES);

            targetCaptcha.out(response.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public Result register(String captcha, String captchaKey, Account account) {
        /**
         * TODO : 这里阔以改为手机注册
         */
//        if (StringUtils.isEmpty(account.getPhone())) {
//            return Result.fail("请输入手机号");
//        }
//        String captchaValue = (String) redisTemplate.opsForValue().get("yygh_" + captchaKey);
        String captchaValue = (String) redisTemplate.opsForValue().get("yygh_" + captchaKey);
        if (!captcha.equals(captchaValue)) {
            return Result.fail("人类验证码不正确");
        }
//        redisTemplate.delete("yygh_" + captchaKey);

        String accountName = account.getName();
        if (StringUtils.isEmpty(accountName)) {
            return Result.fail("用户名不可以为空");
        }

        String password = account.getPwd();
        if (StringUtils.isEmpty(password)) {
            return Result.fail("密码不可以为空");
        }
        List<Account> accounts = this.getAccountByName(accountName);
        if (accounts.size() != 0) {
            return Result.fail("名字已存在");
        }
        account.setPwd(bCryptPasswordEncoder.encode(account.getPwd()));
        account.setName(accountName);
        this.save(account);
        return Result.ok("注册成功");
    }

    @Override
    public Result login(String captcha, String captchaKey, Account account) {
        String captchaValue = (String) redisTemplate.opsForValue().get("yygh_" + captchaKey);
        if (!captcha.equals(captchaValue)) {
            return Result.fail("人类验证码不正确");
        }
//        redisTemplate.delete("yygh_" + captchaKey);

        String accountName = account.getName();
        if (StringUtils.isEmpty(accountName)) {
            return Result.fail("用户名不可以为空");
        }

        String password = account.getPwd();
        if (StringUtils.isEmpty(password)) {
            return Result.fail("密码不可以为空");
        }
        List<Account> accounts = this.getAccountByName(accountName);
        boolean matches = bCryptPasswordEncoder.matches(password, accounts.get(0).getPwd());
        if (!matches) {
            return Result.fail("用户名或密码错误");
        }
        return Result.ok("登录成功");
    }

    @Autowired
    private AccountMapper accountMapper;

    private List<Account> getAccountByName(String name) {
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
//        queryWrapper.orderByDesc("age", "id");
        queryWrapper.eq("name", name);
        return accountMapper.selectList(queryWrapper);
    }
}
